package lu.med.praxiswahl.wahlumed.client.patienten;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

import lu.med.praxiswahl.wahlumed.client.ordonancen.OrdonancenDataset;
import lu.med.praxiswahl.wahlumed.client.utilities.ColumnWidthControler;
import lu.med.praxiswahl.wahlumed.client.utilities.PrintConfiguration;
import lu.med.praxiswahl.wahlumed.client.utilities.TextAreaCharBound;
import lu.med.praxiswahl.wahlumed.client.utilities.UniCode;
import lu.med.praxiswahl.wahlumed.client.wclient.Main;
import lu.med.praxiswahl.wahlumed.client.wclient.PatientenSuchmaske;
import lu.med.praxiswahl.wahlumed.client.wclient.PatientenSuchmaskeListener;
import lu.med.praxiswahl.wahlumed.model.beans.VersicherungAntraegeTBL;

/**
 * 
 * @author Lars Holger Roth
 */
@SuppressWarnings("serial")
public class VersicherungAntraegePanel extends JPanel implements
	PatientenPanelListener, PatientenSuchmaskeListener, ActionListener,
	Printable
{

    private String matricule = "";
    private Main dataManager;
    private PatientenPanel owner;
    private JList versicherungAntragList;
    private DefaultListModel versicherungAntragModel;
    private ArrayList<OrdonancenDataset> versicherungAntrag = new ArrayList<OrdonancenDataset>();
    private TextAreaCharBound versicherungAntragTextArea;
    private JTabbedPane tabbedPane;

    public VersicherungAntraegePanel(Main dataManager, PatientenPanel owner,
	    PatientenSuchmaske search, JTabbedPane tabbedPane)
    {
	super(new BorderLayout());
	this.tabbedPane = tabbedPane;
	this.dataManager = dataManager;
	this.owner = owner;
	search.addSuchmaskeListener(this);

	versicherungAntragModel = new DefaultListModel();
	versicherungAntragList = new JList(versicherungAntragModel);
	JScrollPane versicherungAntragListPane = new JScrollPane(
		versicherungAntragList);
	versicherungAntragListPane.setPreferredSize(new Dimension(
		new ColumnWidthControler(Main.WIDTH_CONFIGURATION_FILE, "versicherungAntrag").getColumnWidth(0), 0));
	this.add(versicherungAntragListPane, BorderLayout.WEST);
	PrintConfiguration inputConf = new PrintConfiguration(
		Main.PATH_INPUT_CONFIG);
	versicherungAntragTextArea = new TextAreaCharBound("", inputConf
		.getCoordsFor("DOKUMENTATION_AC"));
	JScrollPane versicherungAntragPane = new JScrollPane(
		versicherungAntragTextArea);
	JPanel versicherungAntragPanePanel = new JPanel(new BorderLayout());
	versicherungAntragPanePanel.add(versicherungAntragPane,
		BorderLayout.CENTER);
	JButton versicherungAntragNew = new JButton("Neu");
	JButton versicherungAntragButton = new JButton("L" + UniCode.getoe()
		+ "schen");
	JButton versicherungAntragSpeichern = new JButton("Speichern");
	JButton versicherungAntragPrint = new JButton("Drucken");
	JButton versicherungBezeichner = new JButton("Bezeichner "
		+ UniCode.getae() + "ndern");
	JButton versicherungText = new JButton(UniCode.getUE() + "berschreiben");
	versicherungBezeichner.addActionListener(this);
	versicherungText.addActionListener(this);
	versicherungAntragNew.addActionListener(this);
	versicherungAntragButton.addActionListener(this);
	versicherungAntragSpeichern.addActionListener(this);
	versicherungAntragPrint.addActionListener(this);
	JPanel versicherungAntragP = new JPanel(new GridLayout(1, 0));
	versicherungAntragP.add(versicherungAntragNew);
	versicherungAntragP.add(versicherungAntragSpeichern);
	versicherungAntragP.add(versicherungAntragButton);
	versicherungAntragP.add(versicherungAntragPrint);
	versicherungAntragP.add(versicherungBezeichner);
	versicherungAntragP.add(versicherungText);
	versicherungAntragPanePanel
		.add(versicherungAntragP, BorderLayout.NORTH);
	this.add(versicherungAntragPanePanel, BorderLayout.CENTER);
	versicherungAntragList
		.addListSelectionListener(new VersicherungAntragActionListener(
			this));
    }

    public void actionPerformed(ActionEvent e)
    {
	if (e.getActionCommand().equals("L" + UniCode.getoe() + "schen"))
	{
	    // Löscht den ausgewählten Eintrag
	    int index = versicherungAntragList.getSelectedIndex();
	    if (index == -1)
	    {
		return;
	    }
	    dataManager.getVersicherungenAntraegeContext().deleteAntragItem(
		    this.versicherungAntrag.get(index).getId());
	    // Löscht die Einträge auch aus der Anzeige
	    this.versicherungAntragModel.remove(index);
	    this.versicherungAntrag.remove(index);
	    this.versicherungAntragTextArea.setText("");
	}
	else if (e.getActionCommand().equals("Neu"))
	{
	    // Löscht die Eingabefläche zum Schreiben eines neuen Textes
	    clearEditArea();
	}
	else if (e.getActionCommand().equals("Speichern"))
	{
	    // Speichert den Eintrag unter einem Bezeichner
	    if (matricule.equals(""))
	    {
		JOptionPane.showMessageDialog(dataManager, "Sie m"
			+ UniCode.getue() + "ssen eine Patientin ausgew"
			+ UniCode.getae()
			+ "hlt haben,\num den Arztbrief speichern zu k"
			+ UniCode.getoe() + "nnen.");
		return;
	    }
	    else
	    {
		// Eine Patientin ist gewaehlt worden
		// Fragt nach einem eindeutigen Bezeichner
		String input = JOptionPane
			.showInputDialog("Geben Sie einen eindeutigen Bezeichner ein:");
		if (input.equals(""))
		{
		    // Abbruch oder ungueltige Eingabe
		    JOptionPane.showMessageDialog(dataManager,
			    "Der Arztbrief wurde nicht gespeichert.");
		    return;
		}
		// Fuegt das aktuelle Datum hinzu
		GregorianCalendar gc = new GregorianCalendar();
		String date = "" + gc.get(Calendar.DAY_OF_MONTH);
		date += "." + (gc.get(Calendar.MONTH) + 1);
		date += "." + gc.get(Calendar.YEAR);

		Long currentNo = new Long(dataManager.getArztbriefContext()
			.getSubPrimaryKeyIndex());
		currentNo += 10000 * gc.get(Calendar.YEAR);
		currentNo = currentNo + 1;
		dataManager.getVersicherungenAntraegeContext()
			.createAntragItem(gc, matricule, input,
				versicherungAntragTextArea.getText());
		this.refresh();
	    }
	}
	else if (e.getActionCommand().equals("Drucken"))
	{
	    // Druckt auf eine Ordonacen Vorlage
	    if (this.versicherungAntragList.getSelectedIndex() == -1)
	    {
		JOptionPane.showMessageDialog(dataManager, "Sie m"
			+ UniCode.getue()
			+ "ssen einen Befund zum Drucken ausw"
			+ UniCode.getae() + "hlen");
		return;
	    }
	    // ALs erstes Ausgabe des Drucker Dialogs
	    PrinterJob pj = PrinterJob.getPrinterJob();
	    boolean ret = pj.printDialog();
	    if (ret)
	    {
		pj.setPrintable(this);
		try
		{
		    pj.setJobName("ArztbriefDruck");
		    // pj.setCopies(1);
		    pj.print();
		}
		catch (PrinterException p)
		{
		    JOptionPane.showMessageDialog(dataManager,
			    "Es trat ein Fehler beim Drucken auf.");
		}
	    }
	}
	else if (e.getActionCommand().equals(
		"Bezeichner " + UniCode.getae() + "ndern"))
	{
	    String input = JOptionPane
		    .showInputDialog("Geben Sie einen neuen Bezeichner ein:");
	    if (versicherungAntragList.getSelectedIndex() == -1)
		return;
	    if (input != null)
		if (!input.equals(""))
		{
		    dataManager.getVersicherungenAntraegeContext()
			    .update_bezeichner(
				    this.versicherungAntrag.get(
					    versicherungAntragList
						    .getSelectedIndex())
					    .getId(), input);
		    this.versicherungAntragTextArea.setText("");
		    JOptionPane.showMessageDialog(dataManager,
			    "Klicken Sie auf Aktualisieren, um die "
				    + UniCode.getAE() + "nderung zu sehen.");
		}
	}
	else if (e.getActionCommand().equals(UniCode.getUE() + "berschreiben"))
	{
	    int index = versicherungAntragList.getSelectedIndex();
	    if (index == -1)
	    {
		return;
	    }
	    String bez = versicherungAntragTextArea.getText();
	    dataManager.getVersicherungenAntraegeContext().update_text(
		    this.versicherungAntrag.get(index).getId(), bez);
	    this.versicherungAntragTextArea.setText("");
	    JOptionPane.showMessageDialog(dataManager,
		    "Klicken Sie auf Aktualisieren, um die " + UniCode.getAE()
			    + "nderung zu sehen.");
	}
    }

    public void clearEditArea()
    {
	versicherungAntragTextArea.setText("");
    }

    public void modelChanged(String matricule)
    {
	/*
	 * if ((this.matricule.equals(matricule)) &&
	 * (!owner.isAktualisierenModus())) { return; } this.matricule =
	 * matricule; this.refresh();
	 */

	if (this.tabbedPane.getSelectedIndex() == 9)
	{
	    this.matricule = matricule;
	    this.refresh();
	}
    }

    public int print(Graphics g, PageFormat pageFormat, int pageIndex)
	    throws PrinterException
    {
	if (pageIndex >= 1)
	{
	    return Printable.NO_SUCH_PAGE;
	}
	g.setFont(new Font("Times New Roman", Font.BOLD, 12));

	// Hilfslinien als Test
	g.setColor(new Color(0, 0, 0));

	// Drucken des Textes
	// Liest zeilenweise aus und uebertraegt aufs Formular

	int curPos = 110 * 3;
	String txt = this.versicherungAntragTextArea.getText();
	String str = "";
	for (int i = 0; i < txt.length(); i++)
	{
	    if ((txt.charAt(i) == '\n') || (i == txt.length() - 1))
	    {
		if (i == txt.length() - 1)
		{
		    str += txt.charAt(i);
		}
		g.drawString(str, (70), curPos);
		curPos += 12;
		str = "";
	    }
	    else
	    {
		str += txt.charAt(i);
	    }
	}

	// Drucken von Matricule und Name
	g.drawString(matricule, 120, 192); // Matricule
	dataManager.getCustomerContext().getCustomer(matricule);
	String[] nn = dataManager.getCustomerContext().getNachname(matricule);
	g.drawString(nn[0] + " " + nn[1] + " " + nn[2], 120, 192 + 14); // Nachname
	g.drawString(dataManager.getCustomerContext().getVorname(matricule),
		120, 192 + 28); // Name

	// Drucken des Datums
	// Fuegt das aktuelle Datum hinzu
	if (owner.getPrintDatum())
	{
	    GregorianCalendar gc = new GregorianCalendar();
	    String date = "" + gc.get(Calendar.DAY_OF_MONTH);
	    date += "." + (gc.get(Calendar.MONTH) + 1);
	    date += "." + gc.get(Calendar.YEAR);
	    g.drawString(date, 25 * 3, 300);
	}
	if (owner.getPrintAdresse())
	{
	    g.drawString(dataManager.getCustomerContext().getPrivatAnschrift(
		    matricule)
		    + ", "
		    + dataManager.getCustomerContext().getPrivatPLZ(matricule),
		    300, 192);
	}
	return Printable.PAGE_EXISTS;
    }

    public void refresh()
    {
	// Ruft die Liste verfügbarer Einträge für die Matricule ein
	clearEditArea();
	versicherungAntrag.clear();
	versicherungAntragModel.clear();

	// Fragt eine Liste mit allen IDs ab
	VersicherungAntraegeTBL[] vers = dataManager
		.getVersicherungenAntraegeContext().getAntragByCustomer(
			matricule);
	// Fragt die Daten für alle Datensätze ab und speichert die Daten in
	// der zugehörigen Array List

	for (int i = 0; i < vers.length; i++)
	{

	    // Stimmt die Matricule
	    if (!vers[i].getCustomer().getMatrikel_nummer().equals(matricule))
	    {
		continue;
	    }

	    OrdonancenDataset od = new OrdonancenDataset();
	    od.setBezeichner(vers[i].getBezeichner());
	    Calendar c = vers[i].getDatum();
	    int d = c.get(Calendar.DAY_OF_MONTH);
	    String dat = "";
	    if (d < 10)
	    {
		dat = "0" + d;
	    }
	    else
	    {
		dat = "" + d;
	    }
	    d = c.get(Calendar.MONTH) + 1;
	    if (d < 10)
	    {
		dat += ".0" + d + "." + c.get(Calendar.YEAR);
	    }
	    else
	    {
		dat += "." + d + "." + c.get(Calendar.YEAR);
	    }
	    od.setDatum(dat);
	    od.setTxt(vers[i].getText());
	    od.setId(vers[i].getAntrag_nummer());
	    // Fügt die Daten dem Modell hinzu
	    this.versicherungAntrag.add(od);
	    this.versicherungAntragModel.addElement("" + od.getDatum() + "   "
		    + od.getBezeichner());

	}
    }

    public void refreshOnDemand()
    {
	this.refresh();
    }

    public void viewversicherungAntrag()
    {
	int index = versicherungAntragList.getSelectedIndex();
	if (index == -1)
	{
	    return;
	}
	String str = versicherungAntrag.get(index).getTxt();
	versicherungAntragTextArea.setText(str);
    }

    /**
     * @return the matricule
     */
    public String getMatricule()
    {
        return matricule;
    }

    /**
     * @param matricule the matricule to set
     */
    public void setMatricule(String matricule)
    {
        this.matricule = matricule;
    }
}
